import os
import sys
from pathlib import Path
from typing import List
from jinja2 import Environment, FileSystemLoader

# 添加项目根目录到路径
project_root = Path(__file__).parent.parent.parent.parent  # 到达 xjc_MCP_GEN 根目录
sys.path.insert(0, str(project_root))

# 添加 mcp_generator 路径
mcp_generator_path = project_root / "services" / "mcp-generator"
sys.path.insert(0, str(mcp_generator_path))

from mcp_generator.function_manager import FunctionManager

class MCPServerBuilder:
    """
    MCP服务器构建器
    负责根据函数注册表生成完整的MCP服务器脚本
    """
    
    def __init__(self, template_path: str, output_path: str, registry_path: str, functions_dir: str = None):
        self.template_path = template_path
        self.output_path = output_path
        self.functions_dir = functions_dir or os.path.join(os.path.dirname(registry_path), "functions")
        self.function_manager = FunctionManager(registry_path, self.functions_dir)
        
    def build_server_script(self) -> bool:
        """
        构建完整的MCP服务器脚本
        
        Returns:
            bool: 是否成功构建
        """
        try:
            # 使用模板生成服务器脚本（新模板不需要插入工具代码）
            template_dir = os.path.dirname(self.template_path)
            template_name = os.path.basename(self.template_path)
            
            env = Environment(loader=FileSystemLoader(template_dir))
            template = env.get_template(template_name)
            
            # 渲染模板（不需要传递工具代码）
            rendered_content = template.render()
            
            # 写入输出文件
            os.makedirs(os.path.dirname(self.output_path), exist_ok=True)
            with open(self.output_path, 'w', encoding='utf-8') as f:
                f.write(rendered_content)
            
            function_count = self.function_manager.get_function_count()
            print(f"Successfully built MCP server script with {function_count} functions available")
            return True
            
        except Exception as e:
            print(f"Error building server script: {e}")
            self._create_fallback_script()
            return False
    
    def _create_fallback_script(self):
        """创建备用的基础服务器脚本"""
        fallback_content = '''import sys
import os
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..'))

import logging
from datetime import datetime
from utils.MySQLUtil import MySQLUtil
from mcp.server.fastmcp import FastMCP
from fastmcp.exceptions import ToolError
from fastmcp.tools.tool import ToolAnnotations
from typing import Annotated, Dict, Any
from pydantic import Field
import json
from starlette.requests import Request
from starlette.responses import JSONResponse

# Initialize FastMCP server with explicit configuration
mcp = FastMCP(
    name="xjcmcpServer",
    mask_error_details=True,
    host="0.0.0.0", port=8000
)

db = MySQLUtil()

logger = logging.getLogger("xjcmcp")
logging.basicConfig(level=logging.INFO)

# Health check endpoint
@mcp.custom_route("/health", methods=["GET"])
async def health_check(request: Request) -> JSONResponse:
    """Health check endpoint for monitoring server status"""
    try:
        # Test database connection
        db.test_connection()
        return JSONResponse({"status": "healthy", "timestamp": datetime.now().isoformat()})
    except Exception as e:
        logger.error(f"Health check failed: {e}")
        return JSONResponse({"status": "unhealthy", "error": str(e)}, status_code=500)

# Fallback tool when function manager is not available
@mcp.tool(
    name="call_indicator_function",
    description="统一的指标数据获取工具（备用版本）。函数管理器未加载，无可用函数。",
    annotations=ToolAnnotations(
        title="指标数据获取工具（备用）",
        readOnlyHint=True,
        idempotentHint=True
    )
)
def call_indicator_function(
    function_name: Annotated[str, Field(description="要调用的函数名称")],
    parameters: Annotated[Dict[str, Any], Field(description="函数参数字典")] = None
) -> dict:
    """备用的指标数据获取工具"""
    raise ToolError("函数管理器未加载，无可用函数")

# Server execution block
if __name__ == "__main__":
    """
    Server entry point
    
    Runs the MCP server with Server-Sent Events (SSE) transport protocol
    """
    try:
        mcp.run(transport="sse")
    except KeyboardInterrupt:
        logger.info("Shutting down MCP server...")
'''
        
        try:
            with open(self.output_path, 'w', encoding='utf-8') as f:
                f.write(fallback_content)
            print(f"Created fallback server script at {self.output_path}")
        except Exception as e:
            print(f"Error creating fallback script: {e}")
    
    def add_functions_from_excel(self, indicators_data: dict, source_file: str = None) -> int:
        """
        从Excel解析的数据中添加函数
        
        Args:
            indicators_data: Excel解析后的指标数据
            source_file: 源Excel文件名
        
        Returns:
            int: 新增的函数数量
        """
        new_functions_count = 0
        
        for indicator_name, logic_details in indicators_data.items():
            # 这里需要调用函数代码生成器生成代码
            # 为了保持模块解耦，这个方法应该接收已生成的代码
            pass
        
        return new_functions_count
    
    def should_generate_code(self, indicator_name: str, excel_created_at: str = None, excel_updated_at: str = None) -> bool:
        """
        判断是否需要生成代码（预检查）
        
        Args:
            indicator_name: 指标名称
            excel_created_at: Excel中的创建日期
            excel_updated_at: Excel中的更新日期
        
        Returns:
            bool: 是否需要生成代码
        """
        # 检查是否需要生成/更新函数
        existing_function = self.function_manager.functions.get(indicator_name)
        if not existing_function:
            return True  # 新函数需要生成
            
        # 检查更新时间
        if excel_updated_at and existing_function.get('excel_updated_at') != excel_updated_at:
            return True  # 需要更新
            
        return False  # 跳过
    
    def add_function(self, indicator_name: str, code: str, source_file: str = None, 
                    excel_created_at: str = None, excel_updated_at: str = None) -> str:
        """
        添加单个函数
        
        Args:
            indicator_name: 指标名称
            code: 生成的函数代码
            source_file: 源文件名
            excel_created_at: Excel中的创建日期
            excel_updated_at: Excel中的更新日期
        
        Returns:
            str: 操作类型 ('new', 'updated', 'skipped')
        """
        operation_type = self.function_manager.register_function(
            indicator_name, code, source_file, excel_created_at, excel_updated_at
        )
        return operation_type
    
    def remove_function(self, indicator_name: str) -> bool:
        """
        移除函数
        
        Args:
            indicator_name: 指标名称
        
        Returns:
            bool: 是否成功移除
        """
        return self.function_manager.remove_function(indicator_name)
    
    def get_function_info(self, indicator_name: str = None) -> dict:
        """
        获取函数信息
        
        Args:
            indicator_name: 指标名称，如果为None则返回所有函数信息
        
        Returns:
            dict: 函数信息
        """
        return self.function_manager.get_function_info(indicator_name)
    
    def clear_all_functions(self):
        """清空所有函数"""
        self.function_manager.clear_all()
        
    def get_function_list(self) -> list:
        """获取函数列表，用于RAG知识库"""
        return self.function_manager.get_function_list()
    
    def get_function_list_text(self) -> str:
        """获取函数列表文本，用于RAG知识库"""
        return self.function_manager.get_function_list_text()